home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH10 / DELAY18.ASM next >
Encoding:
Assembly Source File  |  1996-02-08  |  3.9 KB  |  188 lines

  1. ; Delay18.asm
  2. ;
  3. ; Software/Hardware based Delay Subroutine
  4.  
  5.         .xlist
  6.         include     stdlib.a
  7.         includelib    stdlib.lib
  8.         .list
  9.  
  10. ; PPI_B is the I/O address of the keyboard/speaker control
  11. ; port.  This program accesses it simply to introduce a
  12. ; large number of wait states on faster machines.  Since the
  13. ; PPI (Programmable Peripheral Interface) chip runs at about
  14. ; the same speed on all PCs, accessing this chip slows most
  15. ; machines down to within a factor of two of the slower
  16. ; machines.
  17.  
  18. PPI_B        equ    61h
  19.  
  20.  
  21. ; RTC is the address of the BIOS timer variable (40:6ch).
  22. ; The BIOS timer interrupt code increments this 32-bit
  23. ; location about every 55 ms (1/18.2 seconds).  The code
  24. ; which initializes everything for the Delay routine
  25. ; reads this location to determine when 1/18th seconds
  26. ; have passed.
  27.  
  28. RTC        textequ    <es:[6ch]>
  29.  
  30.  
  31.  
  32. dseg        segment    para public 'data'
  33.  
  34. ; TimedValue contains the number of iterations the delay
  35. ; loop must repeat in order to waste 1/18.2 seconds.
  36.  
  37. TimedValue    word    0
  38.  
  39. ; RTC2 is a dummy variable used by the Delay routine to
  40. ; simulate accessing a BIOS variable.
  41.  
  42. RTC2        word    0
  43.  
  44.  
  45. dseg        ends
  46.  
  47. ;********************************************************
  48.  
  49.  
  50.  
  51.  
  52.  
  53. cseg        segment    para public 'code'
  54.         assume    cs:cseg, ds:dseg
  55.  
  56. ; Main program which tests out the DELAY subroutine.
  57.  
  58. Main        proc
  59.         mov    ax, dseg
  60.         mov    ds, ax
  61.  
  62.         print
  63.         byte    "Delay test routine",cr,lf,0
  64.  
  65. ; Okay, let's see how long it takes to count down 1/18th
  66. ; of a second.  First, point ES as segment 40h in memory.
  67. ; The BIOS variables are all in segment 40h.
  68. ;
  69. ; This code begins by reading the memory timer variable
  70. ; and waiting until it changes.  Once it changes we can
  71. ; begin timing until the next change occurs.  That will
  72. ; give us 1/18.2 seconds.  We cannot start timing right
  73. ; away because  we might  be in the  middle of a 1/18.2
  74. ; second period.
  75.  
  76.         mov    ax, 40h
  77.         mov    es, ax
  78.         mov    ax, RTC
  79. RTCMustChange:    cmp    ax, RTC
  80.         je    RTCMustChange
  81.  
  82. ; Okay, begin timing the number of iterations it takes
  83. ; for an 18th of a second to pass.  Note that this
  84. ; code must be very similar to the code in the Delay
  85. ; routine.
  86.  
  87.         mov    cx, 0
  88.         mov    si, RTC
  89.         mov    dx, PPI_B
  90.         align    4
  91. TimeRTC:    mov    bx, 50
  92.         align    4
  93. DelayLp:    ;in    al, dx            ;Slow to hardware speed.
  94.         dec    bx
  95.         jne    DelayLp
  96.         cmp    si, RTC
  97.         loope    TimeRTC
  98.  
  99.         neg    cx            ;CX counted down!
  100.         mov    TimedValue, cx        ;Save away
  101.  
  102.         mov    ax, ds
  103.         mov    es, ax
  104.  
  105.         printf
  106.         byte    "TimedValue = %d",cr,lf
  107.         byte    "Press any key to continue",cr,lf
  108.         byte    "This will begin a delay of five seconds",cr,lf,0
  109.         dword    TimedValue
  110.  
  111.         getc
  112.  
  113.  
  114.         mov    cx, 180
  115. DelayIt:    call    Delay18
  116.         loop    DelayIt
  117.  
  118.  
  119.  
  120. Quit:        ExitPgm            ;DOS macro to quit program.
  121. Main        endp
  122.  
  123.  
  124.  
  125. ; Delay- This routine delays for approximately 1/18th second.
  126. ;      Presumably, the variable "TimedValue" in DS has been
  127. ;     initialized with an appropriate count down value
  128. ;     before calling this code.
  129.  
  130. Delay18        proc    near
  131.         push    ds
  132.         push    es
  133.         push    ax
  134.         push    bx
  135.         push    cx
  136.         push    dx
  137.         push    si
  138.  
  139.         mov    ax, dseg
  140.         mov    es, ax
  141.         mov    ds, ax
  142.  
  143. ; The following code contains two loops.  The inside
  144. ; nested loop repeats 10 times.  The outside loop
  145. ; repeats the number of times determined to waste
  146. ; 1/18.2 seconds.  This loop accesses the hardware
  147. ; port "PPI_B" in order to introduce many wait states
  148. ; on the faster processors.  This helps even out the
  149. ; timings on very fast machines by slowing them down.
  150. ; Note that accessing PPI_B is only done to introduce
  151. ; these wait states, the data read is of no interest
  152. ; to this code.
  153.  
  154.         mov    cx, TimedValue
  155.         mov    si, es:RTC2
  156.         mov    dx, PPI_B
  157.  
  158.         align    4
  159. TimeRTC:    mov    bx, 50
  160.         align    4
  161. DelayLp:    ;in    al, dx
  162.         dec    bx
  163.         jne    DelayLp
  164.         cmp    si, es:RTC2
  165.         loope    TimeRTC
  166.  
  167.         pop    si
  168.         pop    dx
  169.         pop    cx
  170.         pop    bx
  171.         pop    ax
  172.         pop    es
  173.         pop    ds
  174.         ret
  175. Delay18        endp
  176.  
  177.  
  178.  
  179.  
  180. cseg            ends
  181.  
  182.  
  183.  
  184. sseg        segment    para stack 'stack'
  185. stk        dw    1024 dup (0)
  186. sseg        ends
  187.         end    Main
  188.